package com.huixi.microspur.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huixi.microspur.commons.enums.ErrorCodeEnum;
import com.huixi.microspur.web.pojo.entity.appeal.WjAppeal;
import com.huixi.microspur.web.pojo.entity.appeal.WjAppealEndorse;
import com.huixi.microspur.web.pojo.entity.dynamic.WjDynamic;
import com.huixi.microspur.web.pojo.entity.user.WjUser;
import com.huixi.microspur.web.pojo.entity.user.WjUserWx;
import com.huixi.microspur.web.pojo.dto.user.WxDecodeUserInfoDTO;
import com.huixi.microspur.web.pojo.dto.user.WxSesssionKeyDTO;
import com.huixi.microspur.web.mapper.WjUserMapper;
import com.huixi.microspur.web.pojo.vo.user.UserDataVO;
import com.huixi.microspur.web.service.*;
import com.huixi.microspur.web.util.CommonUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author xzl
 * @since 2020-01-17
 */
@Service
public class WjUserServiceImpl extends ServiceImpl<WjUserMapper, WjUser> implements WjUserService {



    @Value("${weiJu.appId}")
    private String appId;

    @Value("${weiJu.appSecret}")
    private String appSecret;

    @Resource
    private WjUserService wjUserService;

    @Resource
    private WjAppealService wjAppealService;

    @Resource
    private WjDynamicService wjDynamicService;

    @Resource
    private WjAppealEndorseService wjAppealEndorseService;

    @Resource
    private WjDynamicEndorseService wjDynamicEndorseService;

    @Resource
    private WjUserWxService wjUserWxService;

    @Resource
    private RedisTemplate redisTemplate;





    /**
     *  获取session_key
     * @Author 李辉
     * @Date 2019/11/23 4:31
     * @param code 用户code
     * @return java.lang.String
     **/
    @Override
    public WxSesssionKeyDTO getWxSessionKey(String code){


        StringBuilder result = null;
        try {
            URL url = new URL("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code" +
                    "=" + code + "&grant_type=authorization_code");

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
            String line = null;
            result = new StringBuilder();
            while ((line = br.readLine()) != null) {
                result.append(line);
            }
            connection.disconnect();
        } catch (Exception e) {
            log.error(ErrorCodeEnum.WX000001.msg() + "|" + e.getMessage());
            e.printStackTrace();
        }


        WxSesssionKeyDTO wxSesssionKeyDTO = JSON.parseObject(result.toString(), WxSesssionKeyDTO.class);


        return wxSesssionKeyDTO;

    }




    /**
     *  获取用户加密信息 并且保存
     * @Author 李辉
     * @Date 2019/11/23 4:33
     * @param
     * @return void
     **/
    @Override
    public WxDecodeUserInfoDTO getEncryptionUserInfo(String encryptedData, String session_key, String ivKey) {
        byte[] encode = Base64.decode(encryptedData);
        byte[] aeskey = Base64.decode(session_key);
        byte[] iv = Base64.decode(ivKey);

        String result = null;

        try {
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (aeskey.length % base != 0) {
                int groups = aeskey.length / base + (aeskey.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(aeskey, 0, temp, 0, aeskey.length);
                aeskey = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
            SecretKeySpec spec = new SecretKeySpec(aeskey, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(iv));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(encode);
            if (null != resultByte && resultByte.length > 0) {
                result = new String(resultByte, "UTF-8");
                System.out.println(result);
            }
        } catch (Exception e) {
            log.error(ErrorCodeEnum.USER004.msg() +"|"+ e.getMessage());
        }

        WxDecodeUserInfoDTO wxDecodeUserInfoDTO = JSON.parseObject(result, WxDecodeUserInfoDTO.class);


        return wxDecodeUserInfoDTO;


    }




    /**
     *  根据用户code 获取用户的 openId 和 sessionKey , 来确定有没有授权过。 如果授权发放用户信息 ，没有就创建一个用户
     * @Author 叶秋
     * @Date 2020/2/1 20:17
     * @param code 用户小程序的code
     * @return WjUser 用户信息
     **/
    @Override
    public WjUser detectionUserAuthorization(String code){


        WxSesssionKeyDTO wxSessionKey = getWxSessionKey(code);

        // 根据open_id 检测数据库中是否有此用户
        QueryWrapper<WjUserWx> wjUserWxQueryWrapper = new QueryWrapper<>();
        wjUserWxQueryWrapper.eq("wx_open_id", wxSessionKey.getOpenid());
        WjUserWx wjUserWx = wjUserWxService.getOne(wjUserWxQueryWrapper);

        if(ObjectUtil.isNotNull(wjUserWx)){

            return wjUserService.getById(wjUserWx.getUserId());

        }


        // 检测用户不存在的情况 随机创建用户资料
        WjUser wjUser = CommonUtil.randomCreateUserInfo();
        WjUserWx newWjUserWx = new WjUserWx().setUserId(wjUser.getUserId())
                .setWxOpenId(wxSessionKey.getOpenid());

        boolean save = wjUserService.save(wjUser);
        boolean save1 = wjUserWxService.save(newWjUserWx);

        return wjUser;

    }




    /**
     *  根据用户id 查询用户信息 包括需要查询其他表的一些数据（诉求、动态...）
     * @Author 叶秋
     * @Date 2020/6/1 21:55
     * @param userId
     * @return com.huixi.microspur.commons.util.wrapper.Wrapper
     **/
    @Override
    public UserDataVO getByIdUserData(String userId) {

        WjUser byId = wjUserService.getById(userId);
        UserDataVO userDataVO = new UserDataVO();
        BeanUtil.copyProperties(byId, userDataVO);




        // 查询诉求 数量
        QueryWrapper<WjAppeal> wjAppealQueryWrapper = new QueryWrapper<>();
        wjAppealQueryWrapper.eq("user_id", userId);
        int appealCount = wjAppealService.count(wjAppealQueryWrapper);
        userDataVO.setAppealCount(appealCount);

        // 查询动态 数量
        QueryWrapper<WjDynamic> wjDynamicQueryWrapper = new QueryWrapper<>();
        wjDynamicQueryWrapper.eq("user_id", userId);
        int dynamicCount = wjDynamicService.count(wjDynamicQueryWrapper);
        userDataVO.setDynamicCount(dynamicCount);

        QueryWrapper<WjAppealEndorse> wjAppealEndorseQueryWrapper = new QueryWrapper<>();
        wjAppealEndorseQueryWrapper.eq("user_id", userId);
        int endorseCount = wjAppealEndorseService.count(wjAppealEndorseQueryWrapper);
        userDataVO.setEndorseCount(endorseCount);

        return userDataVO;
    }

}
